package com.jourwon.spring.boot.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.SimpleCache;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.jourwon.spring.boot.annotation.EsDocId;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.get.GetResponse;

/**
 * @author JourWon
 * @date 2024/3/10
 */
public class EsFieldUtils {

    private static final String NULL_STR = "null";

    private static final SimpleCache<Class<?>, String> ID_FIELD_CACHE = new SimpleCache<>();

    private static boolean isNullStrOrBlank(String str) {
        return StrUtil.isBlank(str) || NULL_STR.equals(str);
    }

    /**
     * 获取clazz里面带有EsDocId注解的属性名称
     *
     * @param clazz Bean class
     * @return 带有EsDocId注解的属性名称或null
     */
    public static String getEsDocIdFieldName(Class<?> clazz) {
        String docIdFieldName = ID_FIELD_CACHE.get(clazz);
        if (StrUtil.isBlank(docIdFieldName)) {
            docIdFieldName = ReflectUtil.getFieldName(
                    ArrayUtil.firstMatch((field) -> field.isAnnotationPresent(EsDocId.class),
                            ReflectUtil.getFields(clazz))
            );

            if (StrUtil.isBlank(docIdFieldName)) {
                ID_FIELD_CACHE.put(clazz, NULL_STR);
                docIdFieldName = null;
            } else {
                ID_FIELD_CACHE.put(clazz, docIdFieldName);
            }
        }

        return isNullStrOrBlank(docIdFieldName) ? null : docIdFieldName;
    }

    public static  <T> T getContainEsDocId(GetResponse getResponse, Class<T> clazz) {
        T t = JSON.parseObject(getResponse.getSourceAsString(), clazz);
        final String esDocIdFieldName = getEsDocIdFieldName(clazz);
        if (StringUtils.isNotEmpty(esDocIdFieldName)) {
            BeanUtil.setFieldValue(t, esDocIdFieldName, getResponse.getId());
        }
        return t;
    }

}
